#!/usr/bin/env python3.10
# -*- encoding: utf-8 -*-
"""
@File    :   controllers.py
@Time    :   2024/01/29 09:40:34
@Author  :   windstarry 
@Version :   1.0
"""
# here put the import lib
from datetime import datetime

from django.contrib.auth import get_user_model, authenticate
from ninja_extra import api_controller, route, status
from ninja_extra.permissions import IsAdminUser, IsAuthenticated
from ninja_jwt import schema
from ninja_jwt.authentication import JWTAuth
from ninja_jwt.controller import TokenObtainSlidingController
from ninja_jwt.tokens import SlidingToken
from .schema import (
    LoginSchema,
    UserRetrieveSchema,
    CreateUserSchema,
    EnableDisableUserOutSchema,
    EnableDisableUserSchema,
    UserTokenOutSchema,
)

User = get_user_model()


@api_controller("/users", tags=["用户管理"],auth=JWTAuth())
class UserController:
    @route.get(
        "/info",
        summary="用户信息",
        url_name="user-info",
        response = {201: UserRetrieveSchema},
        permissions=[IsAuthenticated],
    )
    def get_user_info(self,):
        """
        获取用户信息

        :return: UserRetrieveSchema对象,包含用户信息
        """
        user_obj = self.context.request.user
        return user_obj

    @route.post(
        "/register",
        response={201: UserTokenOutSchema},
        summary="用户注册",
        url_name="user-create",
        auth=None,
    )
    def register(self, user_schema: CreateUserSchema):
        user = user_schema.create()
        token = SlidingToken.for_user(user)
        return UserTokenOutSchema(
            user=user,
            token=str(token),
            token_exp_date=datetime.utcfromtimestamp(token["exp"]),
        )

    @route.put(
        "/{int:pk}/enable-disable",
        response=EnableDisableUserOutSchema,
        summary="用户状态",
        url_name="user-enable-disable",
        permissions=[IsAuthenticated, IsAdminUser],
    )
    def enable_disable_user(self, pk: int):
        user_schema = EnableDisableUserSchema(user_id=pk)
        user_schema.update()
        return EnableDisableUserOutSchema(message="更新成功")

    @route.delete(
        "/{int:pk}/delete",
        response=EnableDisableUserOutSchema,
        summary="用户删除",
        url_name="user-delete",
        permissions=[IsAuthenticated, IsAdminUser],
    )
    def delete_user(self, pk: int):
        user_schema = EnableDisableUserSchema(user_id=pk)
        user_schema.delete()
        return self.create_response("", status_code=status.HTTP_204_NO_CONTENT)


@api_controller("/auth", tags=["认证"])
class UserTokenController(TokenObtainSlidingController):
    auto_import = True

    @route.post("/login", response=UserTokenOutSchema, summary="登录", url_name="login")
    def obtain_token(self, auth: LoginSchema):
        """
        获取用户对象并生成令牌

        Args:
            auth (LoginSchema): 用户登录信息

        Returns:
            UserTokenOutSchema: 包含用户对象、令牌和过期时间的输出对象
        """
        # 获取用户对象
        user_obj = authenticate(username=auth.username, password=auth.password)
        # 生成令牌
        token = SlidingToken.for_user(user_obj)
        return UserTokenOutSchema(
            user=user_obj,
            token=str(token),
            # 设置当前时区的时间戳,设置为UTC时间戳使用datetime.utcfromtimestamp()
            token_exp_date=datetime.fromtimestamp(token["exp"]),
        )

    @route.post(
        "/api-token-refresh",
        response=schema.TokenRefreshSlidingSerializer,
        summary="刷新token",
        url_name="refresh",
    )
    def refresh_token(self, refresh_token: schema.TokenRefreshSlidingSchema):
        """
        刷新令牌

        参数:
            refresh_token (schema.TokenRefreshSlidingSchema): 用于刷新令牌的参数对象

        返回:
            refresh (schema.TokenRefreshSlidingSchema): 刷新后的令牌对象
        """
        refresh = schema.TokenRefreshSlidingSerializer(**refresh_token.dict())
        return refresh
